﻿<!--
https://github.com/netnr
https://gitee.com/netnr
https://www.netnr.com
https://zme.ink
-->

<!DOCTYPE html>
<html>
<head>

    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />

    <title>Nginx编辑器 脚本服务</title>

    <meta name="keywords" content="netnr NET牛人 Nginx编辑器" />
    <meta name="description" content="Script Services Nginx配置文件格式化" />

</head>
<body>
                    <div id="LoadingMask" style="position: fixed; top: 0; left: 0; bottom: 0; right: 0; background-color: white; z-index: 9999; background-image:url('/images/loading.svg');background-repeat:no-repeat;background-position:48% 45%"></div>
            <link href="https://code.bdstatic.com/npm/bootstrap@4.5.2/dist/css/bootstrap.min.css" rel="stylesheet">
            <link href="https://code.bdstatic.com/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
            <script src="https://code.bdstatic.com/npm/jquery@3.5.0/dist/jquery.min.js"></script>
            <script src="https://code.bdstatic.com/npm/bootstrap@4.5.2/dist/js/bootstrap.bundle.min.js"></script>
            <script src="https://code.bdstatic.com/npm/jzjs@2.0.2/2.0.2/jz.min.js"></script>
            <link href="https://code.bdstatic.com/npm/netnrnav@1.1.0/src/netnrnav.css" rel="stylesheet" />
            <script src="https://code.bdstatic.com/npm/netnrnav@1.1.0/src/netnrnav.js" defer async></script>
            <script>
                $.ajax({
                    url: '/images/icon.svg?200930',
                    dataType: 'text',
                    success: function (data) {
                        $('body').append('<div class="d-none">' + data + '</div>')
                    }
                })
            </script>

        <link href="/css/global.css?v=DE0bvfxeaNrv9kM04k3iwLx3LJtPPzAo5IWIj2LN6vE" rel="stylesheet" />
        <script src="/js/global.js?v=83bE557i4FM8eaqzTNVIZ3fbAAVZlAFDY06346DgWok"></script>
            <!--导航-->
            <button type="button" class="MenuToggle show-in-mobile btn btn-primary ml-3 mt-3">
                <span class="fa fa-align-justify fa-2x"></span>
            </button>
            <div class="netnrnav horizontal">
                <div class="netnrnav-wrapper">
                    <ul>
                        <li><a href="https://www.netnr.com" class="siteIcon"><img src="/favicon.svg" /> 首页</a></li>
                        <li><a href="https://www.netnr.com/gist/discover" title="代码片段"><span class="fa fa-fw fa-file-code-o"></span> Gist</a></li>
                        <li><a href="https://www.netnr.com/run/discover" title="在线运行代码"><span class="fa fa-fw fa-play"></span> Run</a></li>
                        <li><a href="https://www.netnr.com/doc" title="文档管理"><span class="fa fa-fw fa-book"></span> Doc</a></li>
                        <li><a href="https://www.netnr.com/draw/discover" title="绘制"><span class="fa fa-fw fa-paint-brush"></span> Draw</a></li>
                        <li><a href="/" title="ss.js.org"><span class="fa fa-fw fa-wrench"></span> 服务</a></li>
                        <li>
                            <a class="text-muted"><span class="fa fa-fw fa-ellipsis-h"></span></a>
                            <ul>
                                <li><a target="_blank" title="码云" href="https://gitee.com/netnr"><i class="fa fa-fw fa-git"></i> Gitee <sup><i class="fa small fa-external-link"></i></sup></a></li>
                                <li><a target="_blank" title="GitHub" href="https://github.com/netnr"><i class="fa fa-fw fa-github"></i> GitHub <sup><i class="fa small fa-external-link"></i></sup></a></li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </div>
            <!--标题-->
                <h4 class="m-3">
                    <svg class="titleicon"><use xlink:href="#nginx"></use></svg> Nginx&#x7F16;&#x8F91;&#x5668;
                </h4>
        <div class="min300">
            <div class="container-fluid">
    <div class="row">
        <div class="col-sm-12">
            <div class="input-group">
                <button class="btn btn-warning" id="btnFormatterNginxConf">格式化</button>
                <div class="input-group-prepend">
                    <select class="custom-select" id="seindent">
                        <optgroup label="缩进">
                            <option value="    ">4格</option>
                            <option value="  ">2格</option>
                        </optgroup>
                    </select>
                </div>
                <div class="input-group-prepend">
                    <select class="custom-select" id="senewline">
                        <optgroup label="格式化选项">
                            <option value="1">大括号在行尾</option>
                            <option value="2">大括号在行首（新的一行）</option>
                        </optgroup>
                    </select>
                </div>
            </div>
        </div>
        <div class="col-md-12 mt-2">
            <div id="ebox" class="border position-relative">
                <textarea class="form-control"></textarea>
                <i class="fa fa-arrows-alt fa-fw me-full-btn" title="Switch the full screen"></i>
            </div>
        </div>
    </div>
</div>


<link href="https://cdn.jsdelivr.net/gh/codemirror/codemirror@5.19.0/lib/codemirror.min.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/gh/codemirror/codemirror@5.19.0/lib/codemirror.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/codemirror/codemirror@5.19.0/mode/nginx/nginx.min.js"></script>


<script>

    /**
     * Ported by Yosef on 24/08/2016.
     * from project:
     *  https://github.com/1connect/nginx-config-formatter
     * from file:
     * nginxfmt.py
     *
     */

    "use strict"; function extractTextBySeperator(t, e, r) { void 0 == r && (r = e); var n = new RegExp(e), i = new RegExp(r), o = new RegExp(e + "(.*?)" + r); return n.test(t) && i.test(t) ? t.match(o)[1] : "" } function extractAllPossibleText(t, e, r) { void 0 == r && (r = e); for (var n, i = {}, o = 0, s = e.length > 0 ? e.charCodeAt(0) : "", a = r.length > 0 ? r.charCodeAt(0) : ""; "" != (n = extractTextBySeperator(t, e, r));) { var p = "#$#%#$#placeholder" + o + s + a + "#$#%#$#"; i[p] = e + n + r, t = t.replace(i[p], p), o++ } return { filteredInput: t, extracted: i, getRestored: function () { var t = this.filteredInput; for (var e in i) t = t.replace(e, i[e]); return t } } } function strip_line(t) { var e = t.trim(), r = extractAllPossibleText(e, '"', '"'); return r.filteredInput = r.filteredInput.replace(/\s\s+/g, " "), r.getRestored() } function clean_lines(t) { for (var e = t.split(/\r\n|\r|\n/g), r = 0, n = 0; r < e.length; r++)if (e[r] = e[r].trim(), e[r].startsWith("#") || "" == e[r]) "" == e[r] && n++ >= 2 && (e.splice(r, 1), r--); else { n = 0; var i = e[r] = strip_line(e[r]); if ("}" != i && "{" != i && !i.includes("('{") && !i.includes("}')")) { var o = i.indexOf("#"), s = (o >= 0 && i.slice(o), o >= 0 ? i.slice(0, o) : i), a = s.indexOf("}"); if (a >= 0) { a > 0 && (e[r] = strip_line(s.slice(0, a - 1)), e.insert(r + 1, "}")); var p = strip_line(s.slice(a + 1)); "" != p && e.insert(r + 2, p), s = e[r] } var l = s.indexOf("{"); if (l >= 0) { e[r] = strip_line(s.slice(0, l)), e.insert(r + 1, "{"); var p = strip_line(s.slice(l + 1)); "" != p && e.insert(r + 2, p) } i = s } } return e } function join_opening_bracket(t) { for (var e = 0; e < t.length; e++) { "{" == t[e] && e >= 1 && (t[e] = t[e - 1] + " {", options.trailingBlankLines && t.length > e + 1 && t[e + 1].length > 0 && t.insert(e + 1, ""), t.remove(e - 1)) } return t } function perform_indentation(t) { var e, r, n; e = [], r = 0; for (var i = t, o = 0; o < i.length; o++)n = i[o], !n.startsWith("#") && n.endsWith("}") && r > 0 && (r -= 1), "" !== n ? e.push(options.INDENTATION.repeat(r) + n) : e.push(""), !n.startsWith("#") && n.endsWith("{") && (r += 1); return e } function perform_alignment(t) { for (var e, r = [], n = [], i = t, o = 0, s = 0; s < i.length; s++) { if (!("" === (e = i[s]) || e.endsWith("{") || e.startsWith("#") || e.endsWith("}") || e.trim().startsWith("upstream") || e.trim().contains("location"))) { var a = e.match(/\S+/g); if (a.length > 1) { n.push(e); var p = e.indexOf(a[1]) + 1; o < p && (o = p) } } r.push(e) } for (var l = 0; l < r.length; l++)if (e = r[l], n.includes(e)) { var c = e.match(/\S+/g), f = e.match(/\s+/g)[0]; e = f + c[0] + " ".repeat(o - c[0].length - f.length) + c.slice(1, c.length).join(" "), r[l] = e } return r } function walkSync(t, e, r) { var n = n || require("fs"), i = n.readdirSync(t); return r = r || [], e = e || "", i.forEach(function (i) { n.statSync(t + "/" + i).isDirectory() ? r = walkSync(t + "/" + i, e, r) : i.endsWith(e) && r.push(t + "/" + i) }), r } function modifyOptions(t) { for (var e in t) options[e] = t[e] } String.prototype.trim || (String.prototype.trim = function () { return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") }), String.prototype.startsWith || (String.prototype.startsWith = function (t, e) { return e = e || 0, this.substr(e, t.length) === t }), String.prototype.endsWith || (String.prototype.endsWith = function (t, e) { var r = this.toString(); ("number" != typeof e || !isFinite(e) || Math.floor(e) !== e || e > r.length) && (e = r.length), e -= t.length; var n = r.indexOf(t, e); return -1 !== n && n === e }), String.prototype.includes || (String.prototype.includes = function (t, e) { return "number" != typeof e && (e = 0), !(e + t.length > this.length) && -1 !== this.indexOf(t, e) }), String.prototype.repeat || (String.prototype.repeat = function (t) { if (null == this) throw new TypeError("can't convert " + this + " to object"); var e = "" + this; if (t = +t, t != t && (t = 0), t < 0) throw new RangeError("repeat count must be non-negative"); if (t == 1 / 0) throw new RangeError("repeat count must be less than infinity"); if (t = Math.floor(t), 0 == e.length || 0 == t) return ""; if (e.length * t >= 1 << 28) throw new RangeError("repeat count must not overflow maximum string size"); for (var r = ""; 1 == (1 & t) && (r += e), 0 != (t >>>= 1);)e += e; return r }), Array.prototype.remove || (Array.prototype.remove = function (t, e) { this.splice(t, 1) }), String.prototype.contains || (String.prototype.contains = String.prototype.includes), Array.prototype.insert || (Array.prototype.insert = function (t, e) { this.splice(t, 0, e) }); var INDENTATION = "\t", options = { INDENTATION: INDENTATION }; "undefined" != typeof module && (module.exports = { walkSync: walkSync, perform_alignment: perform_alignment, perform_indentation: perform_indentation, join_opening_bracket: join_opening_bracket, clean_lines: clean_lines, modifyOptions: modifyOptions, strip_line: strip_line });


    /** nginx.js */

    var ebox = $('#ebox');

    var cme = CodeMirror.fromTextArea(ebox.children()[0], {
        mode: 'nginx',
        lineNumbers: true
    })
    cme.setValue(ss.lsStr("txt"));
    cme.on("change", function () {
        ss.ls.txt = cme.getValue();
        ss.lsSave();
    });

    $(window).on('load resize', function () {
        cme.setSize("100%", $(this).height() - ebox.offset().top - 15);
    }).click(function (e) {
        var target = e.target || window.event.srcElement;
        if (target.nodeName == "I" && target.className.indexOf('fa-arrows-alt') >= 0) {
            cme.setSize("100%", $(this).height() - ebox.offset().top - 15);
        }
    })

    $('#btnFormatterNginxConf').click(function () {
        var indent = $('#seindent').val();
        modifyOptions({ INDENTATION: indent });
        var cleanLines = clean_lines(cme.getValue());
        var newline = $('#senewline').val();
        if (newline == 1) {
            modifyOptions({ trailingBlankLines: false });
            cleanLines = join_opening_bracket(cleanLines);
        }
        cleanLines = perform_indentation(cleanLines, indent);
        cme.setValue(cleanLines.join("\n"));
    });
</script>
        </div>
        <a href="javascript:ss.toTop();" class="totop" title="返回顶部">ˆ</a>
</body>
</html>
